﻿using Equin.ApplicationFramework;
using Library;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataConnector
{
    public sealed class DataConnectorLayer
    {
        public Repository<ProductMachineCompatibility, DbContext> R_ProductMachineCompatibility { get; set; }
        public Repository<LabEnviromentProductType, DbContext> R_LabEnvironmentProductType { get; set; }
        public Repository<ProductStateTrail, DbContext> R_ProductStateTrail { get; set; }
        public Repository<ProductCategory, DbContext> R_ProductCategory { get; set; }
        public Repository<V_ProductObject, DbContext> R_V_ProductObject { get; set; }
        public Repository<LabEnvironment, DbContext> R_LabEnvironment { get; set; }
        public Repository<V_ProductType, DbContext> R_V_ProductType { get; set; }
        public Repository<PackageInsert, DbContext> R_PackageInsert { get; set; }
        public Repository<ProductObject, DbContext> R_ProductObject { get; set; }
        public Repository<Manufacturer, DbContext> R_Manufacturer { get; set; }
        public Repository<V_MachineList, DbContext> R_MachineList { get; set; }
        public Repository<MachineType, DbContext> R_MachineType { get; set; }
        public Repository<ProductType, DbContext> R_ProductType { get; set; }
        public Repository<LoginTrail, DbContext> R_LoginTrail { get; set; }
        public Repository<Department, DbContext> R_Department { get; set; }
        public Repository<V_UserList, DbContext> R_V_UserList { get; set; }
        public Repository<UserGroup, DbContext> R_UserGroup { get; set; }
        public Repository<V_Product, DbContext> R_V_Product { get; set; }
        public Repository<Analysis, DbContext> R_Analysis { get; set; }
        public Repository<Machine, DbContext> R_Machine { get; set; }
        public Repository<Product, DbContext> R_Product { get; set; }
        public Repository<State, DbContext> R_State { get; set; }
        public Repository<User, DbContext> R_User { get; set; }

        #region Singleton

        private static readonly DataConnectorLayer instance = new DataConnectorLayer();

        static DataConnectorLayer()
        { }

        private DataConnectorLayer()
        {
            R_ProductMachineCompatibility = new Repository<ProductMachineCompatibility, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_LabEnvironmentProductType = new Repository<LabEnviromentProductType, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_ProductStateTrail = new Repository<ProductStateTrail, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_ProductCategory = new Repository<ProductCategory, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_LabEnvironment = new Repository<LabEnvironment, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_V_ProductObject = new Repository<V_ProductObject, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_PackageInsert = new Repository<PackageInsert, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_ProductObject = new Repository<ProductObject, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_V_ProductType = new Repository<V_ProductType, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_Manufacturer = new Repository<Manufacturer, DbContext> (new DbContext(Helper.ENTITY_NAME));
            R_MachineList = new Repository<V_MachineList, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_MachineType = new Repository<MachineType, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_ProductType = new Repository<ProductType, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_V_UserList = new Repository<V_UserList, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_LoginTrail = new Repository<LoginTrail, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_Department = new Repository<Department, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_UserGroup = new Repository<UserGroup, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_V_Product = new Repository<V_Product, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_Analysis = new Repository<Analysis, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_Product = new Repository<Product, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_Machine = new Repository<Machine, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_State = new Repository<State, DbContext>(new DbContext(Helper.ENTITY_NAME));
            R_User = new Repository<User, DbContext>(new DbContext(Helper.ENTITY_NAME));
        }

        public static DataConnectorLayer Instance
        {
            get
            {
                return instance;
            }
        }

        #endregion

        #region API

        public User Login(string login, string password)
        {
            using (var context = new LabManagerEntities())
            {
                User foundUser = (from user in context.User.Include(Enums.Tablenames.USERGROUP)
                                  where user.Login == login
                                  && user.Password == password
                                  select user).FirstOrDefault();

                if (foundUser != null)
                {
                    LoginTrail(context, foundUser, Enums.LoginState.LOGIN);
                }

                return foundUser;
            }
        }

        public void Logout(User user)
        {
            using (var context = new LabManagerEntities())
            {
                LoginTrail(context, user, Enums.LoginState.LOGOUT);
            }
        }

        #endregion

        #region Helper

        private void LoginTrail(LabManagerEntities context, User user, string lStateName)
        {
            var loginStateName = context.LoginState.SingleOrDefault(m => m.LoginStateName == lStateName);
            var logTrail = new LoginTrail();
            logTrail.LoginStateID = loginStateName.LoginStateID;
            logTrail.UserID = user.UserID;
            logTrail.Timestamp = DateTime.Now;

            context.LoginTrail.Add(logTrail);
            context.SaveChanges();
        }

        #endregion
    }
}
